<script setup lang="ts">
import {onMounted, ref, defineAsyncComponent, unref, computed} from "vue";
import {useRoute} from "vue-router";
import {ftpStorage, serverStorage, webStorage} from "@/storage";
import {onStartExec, onBuildPack, onUploadPack, onZipPack} from "@/utils/upload";
import {Fold} from '@element-plus/icons-vue';
import {ElNotification} from "element-plus";
import {useEventListener} from "@vueuse/core";
import {Local} from "@/utils/storage";
import {emitter} from '@/utils/mitt'
import {findTree} from "@/utils";

const FileIndex = defineAsyncComponent(() => import("@/views/file/FileIndex.vue"))
const WebTerminal = defineAsyncComponent(() => import('@/components/WebTerminal.vue'))

const route = useRoute()
const termRef = ref()
const fileRef = ref()
const growRef = ref()
const id = route.query.id || ''
const type: string = String(route.query.type || 'web')
const ftp = ref<DeployFtpType>({
  title: '成都147',
  id: '',
  host: "192.168.0.147",
  port: 22,
  username: "root",
  password: "hrz81788178.com",
  system: 'linux'
})
const web = ref<WebType>({
  id: '',
  title: '成都147MIS',
  ftp_id: 'test_1111',
  target: '/home/mis/www/',
  source: 'D:\\projects\\MisWWW\\vue-element-plus\\dist_mis',
  exclude: [],
  filename: 'admin',
  writes: []
})

const mousedown = ref(false)
const panelWidth = ref(Local.get('file_panel_width') || 200)
const loading = ref(false)

const getFtp = () => {
  const ftpItem = findTree(unref(ftpStorage), item => item.id === web.value.ftp_id)
  if (ftpItem) {
    ftp.value = ftpItem
  }
}

/**
 * 发布
 * @param alter 只传5分钟内变更的文件（不包含排除的文件）
 */
const onBuild = async (alter?: boolean | undefined) => {
  if (!termRef.value) return
  const row = unref(web)
  try {
    loading.value = true
    emitter.emit('showLoading', {text: '正在发布中...'})
    // 发布
    await onBuildPack(row, type, term.value)
    // 压缩
    const {output, target} = await onZipPack({web: row, alter})
    // 提示
    const message = `\n${web.value.title} - 压缩完成。\n${output}\n`
    ElNotification({
      title: '成功提示',
      message,
      type: 'success',
      position: 'bottom-left'
    })
    stream.value.write(ftp.value.system === 'linux' ? 'date\n' : 'date /t\r')
    onStartExec(target)
    loading.value = false
    emitter.emit('hideLoading')
  } catch (e) {
    const message = e ? String(e) : `\n${web.value.title} - 发布失败\n`
    loading.value = false
    emitter.emit('hideLoading')
    ElNotification({
      title: '错误提示',
      message,
      type: 'error',
      duration: 0
    })
  }
}

/**
 * 压缩
 * @param alter 只传5分钟内变更的文件（不包含排除的文件）
 */
const onZip = async (alter?: boolean | undefined) => {
  if (!termRef.value) return
  const row = unref(web)
  try {
    loading.value = true
    // 压缩
    const {output, target} = await onZipPack({web: row, alter, hash: true})
    // 提示
    const message = `\n${web.value.title} - 压缩完成。\n${output}\n`
    ElNotification({
      title: '成功提示',
      message,
      type: 'success',
      position: 'bottom-left'
    })
    onStartExec(target)
    loading.value = false
  } catch (e) {
    const message = e ? String(e) : `\n${web.value.title} - 压缩失败\n`
    loading.value = false
    ElNotification({
      title: '错误提示',
      message,
      type: 'error',
      duration: 0
    })
  }
}

// /**
//  * 只上传
//  * @param alter 只传5分钟内变更的文件（不包含排除的文件）
//  */
// const onUpload = async (alter?: boolean | undefined) => {
//   if (!termRef.value) return
//   const row = unref(web)
//   try {
//     loading.value = true
//     // 上传
//     await onUploadPack(row, unref(ftp), client.value, stream.value, type)
//     // 提示
//     const message = `\n${web.value.title} - 上传完成。\n${web.value.target}\n`
//     ElNotification({
//       title: '成功提示',
//       message,
//       type: 'success',
//     })
//     termRef.value.stream.write(ftp.value.system === 'linux' ? 'date\n' : 'date /t\r')
//     loading.value = false
//   } catch (e) {
//     const message = e ? String(e) : `\n${web.value.title} - 上传失败\n`
//     loading.value = false
//     ElNotification({
//       title: '错误提示',
//       message,
//       type: 'error',
//     })
//   }
// }

/**
 * 压缩上传
 * @param alter 只传5分钟内变更的文件（不包含排除的文件）
 */
const onZipUpload = async (alter?: boolean | undefined) => {
  if (!termRef.value) return
  const row = unref(web)
  try {
    loading.value = true
    // 压缩
    emitter.emit('showLoading', {text: '正在压缩中...'})
    await onZipPack({web: row, alter})
    // 上传
    emitter.emit('showLoading', {text: '正在上传中...'})
    await onUploadPack(row, unref(ftp), client.value, stream.value, type)
    // 提示
    const message = `${row.title} - 上传完成。\n${row.target}\n`
    ElNotification({
      title: '成功提示',
      message,
      type: 'success',
      position: 'bottom-left'
    })
    stream.value.write(ftp.value.system === 'linux' ? 'date\n' : 'date /t\r')
    if (fileRef.value) fileRef.value.onTimeoutRefresh()
    loading.value = false
    emitter.emit('hideLoading')
  } catch (e) {
    const message = e ? String(e) : `\n${web.value.title} - 上传失败\n`
    loading.value = false
    emitter.emit('hideLoading')
    ElNotification({
      title: '错误提示',
      message,
      type: 'error',
      duration: 0
    })
  }
}

/**
 *  一键发布-压缩-上传
 * @param alter 只传5分钟内变更的文件（不包含排除的文件）
 */
const onBuildZipUpload = async (alter?: boolean | undefined) => {
  if (!termRef.value) return
  const row = unref(web)
  try {
    loading.value = true
    emitter.emit('showLoading', {text: '正在发布中...'})
    // 发布
    await onBuildPack(row, type, term.value)
    // 压缩
    await onZipPack({web: row, alter})
    // 上传
    await onUploadPack(row, unref(ftp), client.value, stream.value, type)
    // 提示
    const message = `${row.title} - 上传完成。\n${row.target}\n`
    ElNotification({
      title: '成功提示',
      message,
      type: 'success',
      position: 'bottom-left'
    })
    stream.value.write(ftp.value.system === 'linux' ? 'date\n' : 'date /t\r')
    if (fileRef.value) fileRef.value.onTimeoutRefresh()
    loading.value = false
    emitter.emit('hideLoading')
  } catch (e) {
    const message = e ? String(e) : `\n${web.value.title} - 上传失败\n`
    loading.value = false
    emitter.emit('hideLoading')
    ElNotification({
      title: '错误提示',
      message,
      type: 'error',
      duration: 0
    })
  }
}

const onMousedown = () => {
  mousedown.value = true
}
const useEvents = () => {
  useEventListener(growRef, 'mousemove', (event) => {
    if (mousedown.value) {
      panelWidth.value = event.pageX
    }
  })
  useEventListener(window, 'mouseup', () => {
    mousedown.value = false
    Local.set('file_panel_width', panelWidth.value)
    termRef.value?.onTermResize()
  })
}

const client = computed(() => {
  return termRef.value?.client
})

const connection = computed(() => {
  return termRef.value?.connection
})

const term = computed(() => {
  return termRef.value?.term
})

const stream = computed(() => {
  return termRef.value?.stream
})

onMounted(() => {
  if (type === 'web') {
    const item = findTree(unref(webStorage), item => item.id === id)
    if (item) {
      web.value = item
      getFtp()
    }
  } else if (type === 'server') {
    const item = findTree(unref(serverStorage), item => item.id === id)
    if (item) {
      web.value = item
      getFtp()
    }
  }
  useEvents()
})

</script>

<template>
  <div class="content">
    <div class="tool e-border-bottom">
      <div style="line-height: 11px" class="font-10">
        <div>
          <span>{{ web.title }}</span>
          <span class="color-danger ml3" v-if="web.filename">{{ web.filename }}</span>
          <span class="ml3">主机：{{ ftp.host }}</span>
        </div>
      </div>
      <el-tooltip
        effect="dark"
        content="一键发布，并生成变更的文件夹"
        placement="bottom">
        <el-button plain @click="onBuild(true)" :disabled="loading" class="ml-auto">只发布</el-button>
      </el-tooltip>
      <el-tooltip
        effect="dark"
        content="不发布，只生成文件夹"
        placement="bottom">
        <el-button plain @click="onZip()" :disabled="loading" class="ml2">生成压缩包</el-button>
      </el-tooltip>
      <el-tooltip
        effect="dark"
        content="不发布，只生成变更的文件夹"
        placement="bottom">
        <el-button plain @click="onZip(true)" :disabled="loading" class="ml2">生成变更压缩包</el-button>
      </el-tooltip>
      <el-tooltip
        effect="dark"
        content="不发布，只上传所有文件（不包含排除文件）"
        placement="bottom">
        <el-button plain @click="onZipUpload()" :disabled="loading" type="primary" class="ml2">
          只上传
        </el-button>
      </el-tooltip>
      <el-tooltip
        effect="dark"
        content="不发布，只上传已变更文件（不包含排除文件）"
        placement="bottom">
        <el-button plain @click="onZipUpload(true)" :disabled="loading" type="primary" class="ml2">
          只上传变更
        </el-button>
      </el-tooltip>
      <el-tooltip
        effect="dark"
        content="一键发布，上传所有文件（不包含排除文件）"
        placement="bottom">
        <el-button plain @click="onBuildZipUpload()" :disabled="loading" type="warning" class="ml2">一键发布</el-button>
      </el-tooltip>
      <el-tooltip
        effect="dark"
        content="一键发布，上传已变更文件（不包含排除文件）"
        placement="bottom">
        <el-button plain @click="onBuildZipUpload(true)" :disabled="loading" type="warning" class="ml2">
          一键变更发布
        </el-button>
      </el-tooltip>
    </div>
    <div class="content-grow" ref="growRef">
      <div :style="{width: `${panelWidth}px`}" class="h100" style="overflow: hidden;">
        <FileIndex
          ref="fileRef"
          v-if="connection"
          :stream="stream"
          :term="term"
          :client="client"
          :connection="connection"
          :toolBack="false"/>
      </div>
      <div class="drop-border">
        <el-icon class="icon" @mousedown="onMousedown">
          <Fold/>
        </el-icon>
      </div>
      <WebTerminal ref="termRef" v-if="ftp.id" :loading="loading" :ftp_id="ftp.id"/>
    </div>
  </div>
</template>

<style scoped>
.content {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.drop-border {
  height: 100%;
  width: 1px;
  background-color: var(--el-border-color);
  position: relative;
  z-index: 10;
}

.drop-border .icon {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%);
  background-color: var(--el-color-primary);
  color: white;
  cursor: col-resize;
  width: 6px;
  height: 50px;
  border-radius: 3px;
}

.content-grow {
  flex-grow: 1;
  display: flex;
}

.content .tool {
  height: 25px;
  display: flex;
  align-items: center;
  padding: 0 3px;
  overflow: hidden;
}
</style>
